package transaction.lcn.order.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import transaction.lcn.common.entity.Result;
import transaction.lcn.common.entity.StatusCode;
import transaction.lcn.common.tcc.WalletPayMoneyService;
import transaction.lcn.common.tcc.WalletPayRequestVO;
import transaction.lcn.common.tcc.WalletPayResponseVO;
import transaction.lcn.order.feign.AccountFeign;
import transaction.lcn.order.feign.StorageFeign;
import transaction.lcn.order.mapper.OrderTblMapper;
import transaction.lcn.order.model.OrderTbl;

@Service
@Slf4j
public class OrderService {

    @Autowired
    private AccountFeign accountFeign;
    @Autowired
    private StorageFeign storageFeign;
    @Autowired
    private OrderTblMapper orderMapper;

    @Autowired
    private WalletPayMoneyService payService;

    //    @GlobalTransactional(rollbackFor = {Exception.class})
//    @LcnTransaction //分布式事务注解
//    @Transactional //本地事务注解
    public Object create(String userId, String commodityCode, Integer count) {
        int orderMoney = count;
        OrderTbl order = new OrderTbl();
        order.setUserId(userId);
        order.setCommodityCode(commodityCode);
        order.setCount(count);
        order.setMoney(orderMoney);
        orderMapper.insertSelective(order);
        Result acc = accountFeign.debit(userId, orderMoney);
        check(acc);
        Result sto = storageFeign.deduct(commodityCode, count);
        check(sto);
        log.info("order 用户 {} 创建订单，数量：{}，金额：{} ->account 账户扣：{}，->storage 库存减少：{}", userId, count, orderMoney, orderMoney, count);
        return "order->account->storage";
    }

    private void check(Result acc) {
        if (!acc.getCode().equals(StatusCode.OK)) {
            log.error("调用失败:{}", acc);
            throw new RuntimeException("调用失败" + acc.getMessage());
        }
    }

    // 其他方式测试
    @Transactional
    public String buySomething(int userId, int money) {

        int orderMoney = money;
        OrderTbl order = new OrderTbl();
        order.setUserId(userId + "");
        order.setCommodityCode("1001");
        order.setCount(1);
        order.setMoney(orderMoney);
        int id = orderMapper.insertSelective(order);
        WalletPayRequestVO request = new WalletPayRequestVO();
        request.setUserId(userId);
        request.setPayAmount(money);

//        WalletPayResponseVO pay = payService.pay(request);
        WalletPayResponseVO pay = accountFeign.debitTcc(request);
        return "id:" + id + " freeze:" + pay.getFreezeAmount();
    }

}
